package com.lzy.cloud.account.facade;

import com.lzy.cloud.account.dto.AccountWalletDto;
import com.lzy.cloud.account.dto.AccountWalletInfoDto;
import com.lzy.cloud.account.remote.OrderApi;
import com.lzy.cloud.account.remote.dtos.OrderExpenseItemDto;
import com.lzy.cloud.account.remote.request.OrderExpenseItemRequest;
import com.lzy.cloud.account.service.AccountWalletInfoService;
import com.lzy.cloud.account.service.AccountWalletService;
import com.lzy.framework.core.ensure.Ensure;
import com.lzy.framework.core.utils.DozerUtils;
import com.lzy.framework.tools.commons.BigDecimalUtil;
import net.sf.json.JSONArray;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.List;

@Component
@Slf4j
public class AccountWalletFacade {

    @Autowired
    private AccountWalletService accountWalletService;
    @Autowired
    private AccountWalletInfoService accountWalletInfoService;

    @Autowired
    private OrderApi orderApi;


    public Boolean isPay(Long memberId,String orderId,Long shopId){
        //根据会员id获取会员钱包主表id
        AccountWalletDto accountWalletDto = accountWalletService.findByMemberIdAndPlatformId(memberId,shopId);
        if(accountWalletDto != null){
            //根据钱包主表id获取钱包附属表的可用余额
            AccountWalletInfoDto accountWalletInfoDto = accountWalletInfoService.selectAvailableAccount(accountWalletDto.getId());
            if(accountWalletInfoDto != null && !BigDecimalUtil.isZeroOrNull(accountWalletInfoDto.getBalance())){
                //获取该订单的余额抵扣总额，判断余额抵扣总额和可用余额的大小
                OrderExpenseItemRequest orderExpenseItemRequest = new OrderExpenseItemRequest();
                orderExpenseItemRequest.setOrderId(orderId);
                orderExpenseItemRequest.setType(3);
                List<OrderExpenseItemDto> orderExpenseItemDtoList = DozerUtils.maps(JSONArray.fromObject(orderApi.queryList(orderExpenseItemRequest).getResult()),OrderExpenseItemDto.class);
                if(orderExpenseItemDtoList != null && orderExpenseItemDtoList.size() > 0){
                    OrderExpenseItemDto orderExpenseItemDto = orderExpenseItemDtoList.get(0);
                    if (orderExpenseItemDto != null && !BigDecimalUtil.isZeroOrNull(orderExpenseItemDto.getAmount())){
                        if(accountWalletInfoDto.getBalance().compareTo(orderExpenseItemDto.getAmount())>=0){
                            //说明钱包可用余额大于或等于订单抵扣金额
                            //则将钱包可用余额中的部分金额（即订单抵扣金额）转为冻结金额,并且更新钱包可用余额
                            //根据钱包id查询会员的冻结金额
                            AccountWalletInfoDto awiDto = accountWalletInfoService.selectBlockAccount(accountWalletDto.getId());
                            if(awiDto != null && !BigDecimalUtil.isZeroOrNull(awiDto.getBalance())){
                                //更新可用余额
                                BigDecimal availableBalance = accountWalletInfoDto.getBalance().subtract(orderExpenseItemDto.getAmount());
                                accountWalletInfoDto.setBalance(availableBalance);
                                accountWalletInfoService.updateAccountWalletInfo(accountWalletInfoDto);
                                //更新冻结金额
                                BigDecimal blockedBalance = awiDto.getBalance().add(orderExpenseItemDto.getAmount());
                                awiDto.setBalance(blockedBalance);
                                accountWalletInfoService.updateAccountWalletInfo(awiDto);
                                return true;
                            }
                        }
                    }
                }
            }
        }
        return false;
    }

    /**
     * 新增钱包
     * @param accountWalletDto
     */
    public void add(AccountWalletDto accountWalletDto) {
        Long accountWalletId = accountWalletService.insert(accountWalletDto);

        for (int i = 1; i <= 5; i++) {
            AccountWalletInfoDto dto = new AccountWalletInfoDto();
            dto.setType(i);
            dto.setWalletId(accountWalletId);
            accountWalletInfoService.add(dto);
        }
    }

    /**
     * 余额变成冻结金额
     * @param dto
     * @return
     */
    public boolean balanceBecomeFrozenAmount(AccountWalletDto dto) {
        // 扣除余额
        AccountWalletDto accountWalletDto = accountWalletService.findByMemberIdAndPlatformId(dto.getMemberId(),dto.getPlatformId());
        Ensure.that(accountWalletDto).isNotNull("00010004");
        AccountWalletInfoDto availableDto = accountWalletInfoService.selectAvailableAccount(accountWalletDto.getId());
        Ensure.that(availableDto).isNotNull("00010004");
        if (availableDto.getBalance().compareTo(dto.getBalance()) < 0) { // 余额不足
            return false;
        }
        availableDto.setBalance(availableDto.getBalance().subtract(dto.getBalance()));
        Ensure.that(accountWalletInfoService.updateBalance(availableDto)).isTrue("00010002");

        // 增加冻结金额
        AccountWalletInfoDto blockDto = accountWalletInfoService.selectBlockAccount(accountWalletDto.getId());
        Ensure.that(blockDto).isNotNull("00010004");
        blockDto.setBalance(blockDto.getBalance().add(dto.getBalance()));
        Ensure.that(accountWalletInfoService.updateBalance(blockDto)).isTrue("00010002");

        return true;
    }

    /**
     * 冻结金额变成余额
     * @param dto
     * @return
     */
    public boolean frozenAmountBecomeBalance(AccountWalletDto dto) {
        // 扣除冻结金额
        AccountWalletDto accountWalletDto = accountWalletService.findByMemberIdAndPlatformId(dto.getMemberId(),dto.getPlatformId());
        Ensure.that(accountWalletDto).isNotNull("00010004");
        AccountWalletInfoDto blockDto = accountWalletInfoService.selectBlockAccount(accountWalletDto.getId());
        Ensure.that(blockDto).isNotNull("00010004");
        if (blockDto.getBalance().compareTo(dto.getBalance()) < 0) { // 冻结金额不足
            return false;
        }
        blockDto.setBalance(blockDto.getBalance().subtract(dto.getBalance()));
        Ensure.that(accountWalletInfoService.updateBalance(blockDto)).isTrue("00010002");

        // 增加余额
        AccountWalletInfoDto availableDto = accountWalletInfoService.selectAvailableAccount(accountWalletDto.getId());
        Ensure.that(availableDto).isNotNull("00010004");
        availableDto.setBalance(availableDto.getBalance().add(dto.getBalance()));
        Ensure.that(accountWalletInfoService.updateBalance(availableDto)).isTrue("00010002");

        return true;
    }
}
